#!/usr/bin/env python
# -*- coding: utf-8 -*-

import gtk
import gtk.gdk
import pango
import ConfigParser
import os
import os.path
import zipfile
import re
import chardet
import shutil

#ustalanie ścieżek
appDirPath = os.path.dirname(__file__)
resDirPath = os.path.join(appDirPath, 'res')
thief1IconPath32 = os.path.join(resDirPath, 'thiefg_32.ico')
thief2IconPath32 = os.path.join(resDirPath, 'thief2_32.ico')
thief1IconPath16 = os.path.join(resDirPath, 'thiefg_16.ico')
thief2IconPath16 = os.path.join(resDirPath, 'thief2_16.ico')

class ConfigManager(ConfigParser.ConfigParser):
	configDirPath = ''
	configFilePath = ''
	missionDir = ''
	selectedMission = ''
	thief1GameDir = ''
	thief2GameDir = ''
	
	def __init__(self):
		'''Ustalenie ścieżek do katalogu i pliku cfg. Utworzenie katalogów i plików
		konfiguracyjnych jeśli nie istnieją'''
		ConfigParser.ConfigParser.__init__(self)
		self.configDirPath = os.path.join(os.path.expanduser('~'), '.gdarkloader')
		self.configFilePath = os.path.join(self.configDirPath, 'gDarkLoader.cfg')
		if not(os.path.exists(self.configDirPath)):
			self.__createConfigDir()
		self.load()
		
		if self.has_section('MISSIONS'):
			if self.has_option('MISSIONS', 'missiondir'):
				self.missionDir = self.get('MISSIONS', 'missiondir')
			if self.has_option('MISSIONS', 'selectedmission'):
				self.selectedMission = self.get('MISSIONS', 'selectedmission')
				
		if self.has_section('THIEF1'):
			if self.has_option('THIEF1', 'gamedir'):
				self.thief1GameDir = self.get('THIEF1', 'gamedir')
				
		if self.has_section('THIEF2'):
			if self.has_option('THIEF2', 'gamedir'):
				self.thief2GameDir = self.get('THIEF2', 'gamedir')
		
	def __createConfigDir(self):
		'''Tworzy katalog z konfiguracją w katalogu domowym. Inicjuje konfiguracje
		wartościami domyślnymi'''
		os.mkdir(self.configDirPath)
		
	def save(self):
		if not(self.has_section('MISSIONS')):
			self.add_section('MISSIONS')
		self.set('MISSIONS', 'missiondir', self.missionDir)
		if not(self.has_section('THIEF1')):
			self.add_section('THIEF1')
		self.set('THIEF1', 'gamedir', self.thief1GameDir)
		if not(self.has_section('THIEF2')):
			self.add_section('THIEF2')
		self.set('THIEF2', 'gamedir', self.thief2GameDir)
		f = open(self.configFilePath, 'w')
		self.write(f)
		f.close()
		
	def load(self):
		self.read(self.configFilePath)
		
#Odczytaj konfigurację
configManager = ConfigManager()

thief1WorkingDir = os.path.join(configManager.configDirPath, 'thief_dp')
thief2WorkingDir = os.path.join(configManager.configDirPath, 'thief_ma')

#budowa gui
gui = gtk.Builder()
gladeFilePath = os.path.join(os.path.dirname(__file__), 'gDarkLoader.glade')
gui.add_from_file(gladeFilePath)
mainWindow = gui.get_object('mainWindow')
missionTreeView = gui.get_object('missionTreeView')
readmeTextView = gui.get_object('readmeTextView')
readmeTextBuffer = gui.get_object('readmeTextBuffer')
missionListStore = gui.get_object('missionListStore')
imageThief1_32 = gui.get_object('thief1Icon32')
imageThief2_32 = gui.get_object('thief2Icon32')
imageThief1_16 = gui.get_object('thief1Icon16')
imageThief2_16 = gui.get_object('thief2Icon16')
currentThiefImage = gui.get_object('currentThiefImage')
imageMenuItemRunThief1 = gui.get_object('imageMenuItemRunThief1')
imageMenuItemRunThief2 = gui.get_object('imageMenuItemRunThief2')
labelMissionName = gui.get_object('LabelMissionName')
labelAuthor = gui.get_object('LabelAuthor')
labelCustomSounds = gui.get_object('LabelCustomSounds')
labelCustomObjects = gui.get_object('LabelCustomObjects')
labelMap = gui.get_object('LabelMap')
labelAutomap = gui.get_object('LabelAutomap')
preferencesDialog = gui.get_object('PreferencesDialog')
missionDirEntry = gui.get_object('PreferencesDialog_MissionDirEntry')
aboutDialog = gui.get_object('AboutDialog')
preferencesDialog_Thief1Dir = gui.get_object('preferencesDialog_Thief1Dir')
preferencesDialog_Thief2Dir = gui.get_object('preferencesDialog_Thief2Dir')
toolButtonRunThief1 = gui.get_object('toolbuttonRunThief1')
toolButtonRunThief2 = gui.get_object('toolbuttonRunThief2')

#ładowanie zasobów
imageThief1_32.set_from_file(thief1IconPath32)
imageThief2_32.set_from_file(thief2IconPath32)
imageThief1_16.set_from_file(thief1IconPath16)
imageThief2_16.set_from_file(thief2IconPath16)

class GameType:
	GAME_UNKNOWN, GAME_THIEF_DARK_PROJECT, GAME_THIEF_GOLD, GAME_THIEF_METAL_AGE = range(4)

class Game:
	ICON_THIEF1 = imageThief1_16.get_pixbuf()
	ICON_THIEFGOLD = imageThief1_16.get_pixbuf()
	ICON_THIEF2 = imageThief2_16.get_pixbuf()
		
class MetadataManager:
	'''Klasa zarządzajaca metadanymi o misjach'''
	__METADATA_DIR = os.path.join(configManager.configDirPath, 'metadata')
	
	def __init__(self):
		if not(os.path.exists(self.__METADATA_DIR)):
			os.mkdir(self.__METADATA_DIR)
		self.updateMissionInfo()
			
	def updateMissionInfo(self):
		'''Porównaj pliki zip z plikami .mission. Ustal co usunać a co dodać.'''
		#sprawdź czy każdy plik zip ma swój odpowiednik w postaci pliku .mission
		for root, dirs, files in os.walk(configManager.missionDir):
			for zipFilename in files:
				zipFilePath = os.path.join(root, zipFilename)
				#czy plik meta istnieje?
				cacheFilePath = os.path.join(self.__METADATA_DIR, zipFilename + '.mission')
				if os.path.exists(cacheFilePath):
					#czy plik zip ma późniejszą datę modyfikacji niż plik meta?
					if os.path.getmtime(zipFilePath) > os.path.getmtime(cacheFilePath):
						self.addMissionInfo(zipFilePath)
				else:
					self.addMissionInfo(zipFilePath)
		#sprawdź czy każdy plik .mission ma swój odpowiednik w postaci pliku zip
		for missionFileName in os.listdir(self.__METADATA_DIR)[1:]:
			fileName = os.path.splitext(missionFileName)[0]
			zipFileName = os.path.join(configManager.missionDir, fileName)
			if not(os.path.exists(zipFileName)):
				os.remove(os.path.join(self.__METADATA_DIR, missionFileName))
	
	def addMissionInfo(self, zipFilePath):
		zipFileName = os.path.split(zipFilePath)[1]
		metafile = open(os.path.join(self.__METADATA_DIR, zipFileName + '.mission'), 'w')
		readmeText = self.__getMissionReadme(zipFilePath)
		encoding = chardet.detect(readmeText)['encoding']
		if encoding:
			try:
				readmeText = readmeText.decode(encoding)
			except UnicodeDecodeError:
				pass
		missionGame = GameType.GAME_UNKNOWN
		missionTitle = os.path.splitext(zipFileName)[0]
		if readmeText:
			#ustal grę
			games = {
					'thief[:]{0,1}[ ]{0,1}gold':(imageThief1_16.get_pixbuf(), GameType.GAME_THIEF_DARK_PROJECT),
					'thief[ 1]{0,1}[:]{0,1} the dark project':(imageThief1_16.get_pixbuf(), GameType.GAME_THIEF_GOLD),
					'thief 2: the metal age':(imageThief2_16.get_pixbuf(), GameType.GAME_THIEF_METAL_AGE)
					}
			
			for i in games.keys():
				m = re.search(i, readmeText, re.I)
				if m:
					missionGame = games[i][1]
					break
			#ustal tytuł misji
			m = re.search('[Mission ]{0,1}Title[\t ]{0,}:(.*?)\n', readmeText, re.I)
			if m:
				missionTitle = m.group(1).strip()
			
			#ustal autora
			missionAuthor = 'N/A'
			m = re.search('Author[ \t]{0,}:(.*?)\n', readmeText, re.I)
			if m:
				missionAuthor = m.group(1)
			
			#czy misja posiada nowe dźwięki
			newSounds = 'N/A'
			m = re.search('[New|Custom] Sounds[ \t:]*([No|Yes]{2,3})', readmeText, re.I)
			if m:
				newSounds = m.group(1)
				#Yes/No powinno być zawsze pisane z wielkiej litery
				newSounds = newSounds[0].upper() + newSounds[1:].lower()
			
			#czy misja posiada nowe obiekty
			newObjects = 'N/A'
			m = re.search('[New|Custom] Objects[ \t:]*([No|Yes]{2,3})', readmeText, re.I)
			if m:
				newObjects = m.group(1)
				newObjects = newObjects[0].upper() + newObjects[1:].lower()

			#czy w misji występuje mapa
			map = 'N/A'
			m = re.search('Map[ \t:]*([No|Yes]{2,3})', readmeText, re.I)
			if m:
				map = m.group(1)
				map = map[0].upper() + map[1:].lower()
				
			#czy automapa występuje w misji
			automap = 'N/A'
			m = re.search('Auto Map[ \t:]*([No|Yes]{2,3})', readmeText, re.I)
			if m:
				automap = m.group(1)
				automap = automap[0].upper() + automap[1:].lower()
		metafile.write('GameType: %s\n' % str(missionGame))
		metafile.write('MissionTitle: %s\n' % missionTitle)
		metafile.write('MissionAuthor: %s\n' % missionAuthor)
		metafile.write('NewSounds: %s\n'% newSounds)
		metafile.write('NewObjects: %s\n' % newObjects)
		metafile.write('Map: %s\n' % map)
		metafile.write('Automap: %s\n' % automap)
		metafile.write(readmeText)
		metafile.close()
		
	def getMissionInfo(self, zipFilePath):
		zipFileName = os.path.split(zipFilePath)[1]
		metafilePath = os.path.join(self.__METADATA_DIR, zipFileName + '.mission')
		retVal = {
				'GameType': GameType.GAME_UNKNOWN,
				'MissionTitle':'',
				'MissionAuthor':'',
				'NewSounds':'',
				'NewObjects':'',
				'Map':'',
				'Automap':'',
				'Readme':'Brak'
		}
		if not(os.path.exists(metafilePath)):
			self.addMissionInfo(zipFilePath)
		if os.path.isfile(metafilePath):
			metafile = open(metafilePath, 'r')
			retVal['GameType'] = int(metafile.readline().strip().split(': ')[1])
			retVal['MissionTitle'] = metafile.readline().strip().split(': ')[1]
			retVal['MissionAuthor'] = metafile.readline().split(': ')[1].strip()
			retVal['NewSounds'] = metafile.readline().split(': ')[1].strip()
			retVal['NewObjects'] = metafile.readline().split(': ')[1].strip()
			retVal['Map'] = metafile.readline().split(': ')[1].strip()
			retVal['Automap'] = metafile.readline().split(': ')[1].strip()
			retVal['Readme'] = metafile.read()
			metafile.close()
		return retVal
		
	def __getMissionReadme(self, filename):
		'''Wyciąga z archiwum zip zawartość pliku readme'''
		fileContents = 'Plik zip wydaje się być uszkodzony'
		if zipfile.is_zipfile(filename):
			try:
				zipFile = zipfile.ZipFile(filename, 'r')
				for i in zipFile.namelist():
					if i[-4:] == '.txt':
						fileContents = zipFile.read(i).replace('\r', '')
						break
				zipFile.close()
			except IOError:
				print('Błąd podczas odczytywania README misji %s. Pomijam.' % filename)
		return fileContents

class MissionLoader:
	_WORKING_DIR = None
	
	def __init__(self):
		self._WORKING_DIR = self._getWorkingDir()
		if not(os.path.exists(self._WORKING_DIR)):
			os.mkdir(self._WORKING_DIR)
		
	def _createSymbolicLinks(self, gameDir, workingDir):
		'''utwórz dowiązania symboliczne do plików z katalogu gry
		które jeszcze nie istnieją w katalogu WORKING_DIR'''
		for filename in os.listdir(gameDir):
			if (filename != '.') or (filename != '..'):
				srcPath = os.path.join(gameDir, filename)
				destPath = os.path.join(workingDir, filename)
				if not(os.path.exists(destPath)):
					os.symlink(srcPath, destPath)
	
	def _getExecutablePath(self):
		pass
	
	def _getGameDirectory(self):
		'''Metoda powinna zwracać ścieżke do katalogu z grą'''
		pass
	
	def _getWorkingDir(self):
		pass
	
	def installMission(self, missionArchive):
		self.__clearMission()
		missionArchivePath = os.path.join(configManager.missionDir, missionArchive)
		if os.path.exists(missionArchivePath):
			z = zipfile.ZipFile(missionArchivePath, 'r')
			z.extractall(self._WORKING_DIR)
			z.close()
			self._createSymbolicLinks(self._getGameDirectory(), self._WORKING_DIR)
		else:
			print('Error: Plik archiwum %s misji nie istnieje' % missionArchivePath)
			
	def __clearMission(self):
		'''Usuwa wszystkie pliki i dowiązania symboliczne z _WORKING_DIR'''
		shutil.rmtree(self._WORKING_DIR)

class Thief1MissionLoader(MissionLoader):
	def _getExecutablePath(self):
		return os.path.join(self._WORKING_DIR, 'thief1.exe')
	
	def _getGameDirectory(self):
		return configManager.get('THIEF1', 'gamedir')
	
	def _getWorkingDir(self):
		return os.path.join(configManager.configDirPath, 'thief_dp')
	
class Thief2MissionLoader(MissionLoader):
	def _getExecutablePath(self):
		return os.path.join(self._WORKING_DIR, 'thief2.exe')
	
	def _getGameDirectory(self):
		return configManager.get('THIEF2', 'gamedir')
	
	def _getWorkingDir(self):
		return os.path.join(configManager.configDirPath, 'thief_ma')
	
metadataManager = MetadataManager()

def __onToolButtonRunThief2Clicked(e):
	thief2Executable = os.path.join(configManager.thief2GameDir, 'thief2.exe')
	os.system('wine %s' % thief2Executable)
		
def __onToolButtonRunThief1Clicked(e):
	thief1Executable = os.path.join(configManager.thief1GameDir, 'thief.exe')
	os.system('wine %s' % thief1Executable)
		
def __onRowActivated(treeview, path, view_column):
	#Ustal zaznaczony wiersz
	selection = treeview.get_selection()
	if selection:
		selectedItem = selection.get_selected()
		if selectedItem:
			missionFileName = selectedItem[0].get_value(selectedItem[1], 2)
			currentThiefImage.set_from_pixbuf(None)
				
			#wczytanie tekstu do kontrolki
			missionInfo = metadataManager.getMissionInfo(missionFileName)
			if missionInfo:
				#ustawienie ikony gry
				if missionInfo['GameType'] == GameType.GAME_THIEF_DARK_PROJECT:
					currentThiefImage.set_from_pixbuf(imageThief1_32.get_pixbuf())
				elif missionInfo['GameType'] == GameType.GAME_THIEF_GOLD:
					currentThiefImage.set_from_pixbuf(imageThief1_32.get_pixbuf())
				elif missionInfo['GameType'] == GameType.GAME_THIEF_METAL_AGE:
					currentThiefImage.set_from_pixbuf(imageThief2_32.get_pixbuf())
				labelMissionName.set_text(missionInfo['MissionTitle'])
				labelAuthor.set_text(missionInfo['MissionAuthor'])
				labelCustomSounds.set_text(missionInfo['NewSounds'])
				labelCustomObjects.set_text(missionInfo['NewObjects'])
				labelMap.set_text(missionInfo['Map'])
				labelAutomap.set_text(missionInfo['Automap'])
				readmeTextBuffer.set_text(missionInfo['Readme'])

def appendMission(missionPath):
	#otwórz archiwum
	missionInfo = metadataManager.getMissionInfo(missionPath)
	icon = None
	if missionInfo['GameType'] == GameType.GAME_THIEF_DARK_PROJECT:
		icon = Game.ICON_THIEF1
	elif missionInfo['GameType'] == GameType.GAME_THIEF_GOLD:
		icon = Game.ICON_THIEFGOLD
	elif missionInfo['GameType'] == GameType.GAME_THIEF_METAL_AGE:
		icon = Game.ICON_THIEF2
	#dodaj do listy
	missionListStore.append((icon, missionInfo['MissionTitle'], missionPath, missionInfo['GameType']))
	
def __getSelectedMission():
	selection = missionTreeView.get_selection()
	if selection:
		rowIter = selection.get_selected()[1]
		if rowIter:
			missionFileName = missionListStore.get_value(rowIter, 2)
			gameType = missionListStore.get_value(rowIter, 3)
			return (rowIter, missionFileName, gameType)
	return None

def __onDestroy(e):
	#zapisz konfigurację
	selectedMission = __getSelectedMission()
	if selectedMission:
		configManager.set('MISSIONS', 'selectedMission', __getSelectedMission()[1])
		configManager.save()
		
	#zakończ program
	gtk.main_quit()

def __onPreferencesDialogButonCancelClick(e):
	preferencesDialog.hide()
	
def __onToolButtonPreferences(e):
	preferencesDialog.show_all()

def __onPreferencesDialogShow(e):
	#odczytaj konfigurację i wypełnij danymi kontrolki
	missionDirEntry.set_text(configManager.missionDir)
	preferencesDialog_Thief1Dir.set_text(configManager.thief1GameDir)
	preferencesDialog_Thief2Dir.set_text(configManager.thief2GameDir)

def __onPreferencesDialogButtonSaveClick(e):
	#zapisz ustawienia do pliku
	configManager.missionDir = missionDirEntry.get_text()
	configManager.thief1GameDir = preferencesDialog_Thief1Dir.get_text()
	configManager.thief2GameDir = preferencesDialog_Thief2Dir.get_text()
	configManager.save()
	preferencesDialog.hide()

def __onMenuItemAboutActivate(e):
	aboutDialog.run()

def __onAboutDialogResponse(e, a):
	aboutDialog.hide()

def __onMissionsDirEntryButton(e):
	dlg = gtk.FileChooserDialog('Choose folder containing fan missions', mainWindow, gtk.FILE_CHOOSER_ACTION_SELECT_FOLDER, (gtk.STOCK_CANCEL, gtk.RESPONSE_CANCEL, gtk.STOCK_OK, gtk.RESPONSE_OK))
	if dlg.run() == gtk.RESPONSE_OK:
		missionDirEntry.set_text(dlg.get_filename())
	dlg.destroy()

def __onThief1EntryButton(e):
	dlg = gtk.FileChooserDialog('Choose Thief 1 installation directory', mainWindow, gtk.FILE_CHOOSER_ACTION_SELECT_FOLDER, (gtk.STOCK_CANCEL, gtk.RESPONSE_CANCEL, gtk.STOCK_OK, gtk.RESPONSE_OK))
	if dlg.run() == gtk.RESPONSE_OK:
		preferencesDialog_Thief1Dir.set_text(dlg.get_filename())
	dlg.destroy()
	
def __onThief2EntryButton(e):
	dlg = gtk.FileChooserDialog('Choose Thief 2 installation directory', mainWindow, gtk.FILE_CHOOSER_ACTION_SELECT_FOLDER, (gtk.STOCK_CANCEL, gtk.RESPONSE_CANCEL, gtk.STOCK_OK, gtk.RESPONSE_OK))
	if dlg.run() == gtk.RESPONSE_OK:
		preferencesDialog_Thief2Dir.set_text(dlg.get_filename())
	dlg.destroy()

def __onMenuItemPreferencesActivate(e):
	__onToolButtonPreferences(e)
	
def __onToolButtonInstallMission(e):
	archiveFilename, gameType = __getSelectedMission()[1:3]
	gameLoader = None
	if gameType == GameType.GAME_THIEF_METAL_AGE:
		gameLoader = Thief2MissionLoader()
		gameLoader.installMission(archiveFilename)
	elif (gameType == GameType.GAME_THIEF_DARK_PROJECT) or (gameType == GameType.GAME_THIEF_GOLD):
		gameLoader = Thief1MissionLoader()
		gameLoader.installMission(archiveFilename)
	else:
		print('Error: Nie ustalono rodzaju gry.')

def __onToolButtonPlayMission(e):
	archiveFilename, gameType = __getSelectedMission()[1:3]
	gameLoader = None
	if gameType == GameType.GAME_THIEF_METAL_AGE:
		gameLoader = Thief2MissionLoader()
		gameLoader.installMission(archiveFilename)
		__onThief2EntryButton(e)
	elif (gameType == GameType.GAME_THIEF_DARK_PROJECT) or (gameType == GameType.GAME_THIEF_GOLD):
		gameLoader = Thief1MissionLoader()
		gameLoader.installMission(archiveFilename)
		__onToolButtonRunThief1Clicked(e)
	else:
		print('Error: Nie ustalono rodzaju gry.')
	
#podłączanie zdarzeń
gui.connect_signals({
	'on_mainWindow_destroy':__onDestroy,
	'on_missionTreeView_row_activated':__onRowActivated,
	'on_imageMenuItemQuit_activate':__onDestroy,
	'on_toolButtonRunThief2_clicked':__onToolButtonRunThief2Clicked,
	'on_imageMenuItemThief2_activate':__onToolButtonRunThief2Clicked,
	'on_toolbuttonRunThief1_clicked':__onToolButtonRunThief1Clicked,
	'on_preferencesDialog__ButtonCancel_clicked':__onPreferencesDialogButonCancelClick,
	'on_toolbuttonPreferences_clicked':__onToolButtonPreferences,
	'on_PreferencesDialog_show':__onPreferencesDialogShow,
	'on_PreferencesDialog_ButtonSave_clicked':__onPreferencesDialogButtonSaveClick,
	'on_menuitemAbout_activate':__onMenuItemAboutActivate,
	'on_AboutDialog_response':__onAboutDialogResponse,
	'on_missionsDirEntryButon_clicked':__onMissionsDirEntryButton,
	'on_button1_clicked':__onThief1EntryButton,
	'on_button2_clicked':__onThief2EntryButton,
	'on_imagemenuitemPreferences_activate':__onMenuItemPreferencesActivate,
	'on_toolbuttonInstallMission_clicked':__onToolButtonInstallMission,
	'on_toolbuttonPlayMission_clicked':__onToolButtonPlayMission
})
		
#tworzenie kolumn dla listy
pixbufRenderer = gtk.CellRendererPixbuf()
pixbufColumn = gtk.TreeViewColumn('Game', pixbufRenderer)
pixbufColumn.add_attribute(pixbufRenderer, 'pixbuf', 0)
missionTreeView.append_column(pixbufColumn)

textRenderer = gtk.CellRendererText()
textColumn = gtk.TreeViewColumn('Mission Name', textRenderer)
textColumn.add_attribute(textRenderer, 'text', 1)
missionTreeView.append_column(textColumn)
		
#fix: dodawanie obrazków do pozycji menu
imageMenuItemRunThief1.set_image(imageThief1_16)
imageMenuItemRunThief2.set_image(imageThief2_16)
#currentThiefImage.set_from_pixbuf(imageThief2_32.get_pixbuf())
				
#usawienie domyślnej czcionki dla tekstu
readmeTextView.modify_font(pango.FontDescription('courier new 10'))
		
#znajdź wszystkie misje i dodaj je do listy
if configManager.missionDir:
	for root, dirs, files in os.walk(configManager.missionDir):
		for f in files:
			fullPath = os.path.join(root, f)
			m = os.path.splitext(f)
			if m[1] == '.zip':
				appendMission(fullPath)
		
#zaznacz misję, która była zaznaczona podczas wyłączania programu
if configManager.selectedMission:
	searchedIter = missionListStore.get_iter_first()
	for i in range(missionListStore.iter_n_children(None)):
		currentIter = missionListStore.iter_nth_child(None, i)
		testedMissionFileName = missionListStore.get_value(currentIter, 2)
		if testedMissionFileName == configManager.selectedMission:
			searchedIter = currentIter
			break
	if searchedIter:
		searchedPath = missionListStore.get_path(searchedIter)
		missionTreeView.get_selection().select_iter(searchedIter)
		missionTreeView.scroll_to_cell(searchedPath, pixbufColumn)
		missionTreeView.row_activated(searchedPath, textColumn)
		
#Deaktywuj przyciski uruchamiania gier jeśli ścieżki do nich nie
#są zapisane w konfiguracji
if not(configManager.thief1GameDir):
	toolButtonRunThief1.set_sensitive(False)
if not(configManager.thief2GameDir):
	toolButtonRunThief2.set_sensitive(False)

gtk.main()

